package models

import (
	"fanqiechaodan-blog/config"
	"go.uber.org/zap"
	"html/template"
	"io"
	"reflect"
	"strings"
	"time"
)

const HTML_SUFFIX = ".html"

type TemplateBlog struct {
	*template.Template
}

func (t *TemplateBlog) WriteData(w io.Writer, data any) {
	err := t.Execute(w, data)
	if err != nil {
		zap.S().Errorf("WriterData error,err:%s", err.Error())
		_, err = w.Write([]byte("加载失败"))
	}
}

func (t *TemplateBlog) WriteError(w io.Writer, err error) {
	if err != nil {
		_, err = w.Write([]byte("加载失败"))
	}
}

type HtmlTemplate struct {
	Category   TemplateBlog `json:"category"`
	Custom     TemplateBlog `json:"custom"`
	Detail     TemplateBlog `json:"detail"`
	Home       TemplateBlog `json:"home"`
	Index      TemplateBlog `json:"index"`
	Login      TemplateBlog `json:"login"`
	Pigeonhole TemplateBlog `json:"pigeonhole"`
	Writing    TemplateBlog `json:"writing"`
}

func InitTemplate(dirPath string) (*HtmlTemplate, error) {
	var res *HtmlTemplate
	htmlNames := config.Cfg.Viewer.HtmlName
	var m = make(map[string]TemplateBlog)
	for _, name := range htmlNames {
		htmlName := name + HTML_SUFFIX
		t := template.New(htmlName)
		// 涉及到的公共模板
		home := dirPath + "home.html"
		footer := dirPath + "layout/footer.html"
		header := dirPath + "layout/header.html"
		pagination := dirPath + "layout/pagination.html"
		personal := dirPath + "layout/personal.html"
		post := dirPath + "layout/post-list.html"
		t.Funcs(template.FuncMap{"isODD": IsODD, "getNextName": GetNextName, "date": Date, "dateDay": DateDay})
		t, err := t.ParseFiles(dirPath+htmlName, home, footer, header, pagination, personal, post)
		if err != nil {
			zap.S().Errorf("解析模板:%s失败,原因:%s", htmlName, err.Error())
			return nil, err
		}
		m[name] = TemplateBlog{t}
	}
	res = &HtmlTemplate{}
	for key, value := range m {
		fieldValue := reflect.ValueOf(res).Elem().FieldByName(Title(key))
		if fieldValue.IsValid() && fieldValue.CanSet() {
			fieldValue.Set(reflect.ValueOf(value))
		}
	}
	return res, nil
}

// Title 将首字母大写返回
func Title(key string) string {
	return strings.ToUpper(key[:1]) + key[1:]
}

func IsODD(num int) bool {
	return num%2 == 0
}

func GetNextName(strs []string, index int) string {
	return strs[index+1]
}

func Date(layout string) string {
	return time.Now().Format(layout)
}

func DateDay(date time.Time) string {
	return date.Format("2006-01-02 15:04:05")
}
